// 方法集合
var initPageBtns = function (pages, curPage) {
  var btnGroup = '',
    oBtnBox = document.getElementsByClassName('J_btnBox')[0];

  render();

  function pageBtnTpl(type, num) {
    switch (type) {
      //按钮状态
      case 'btn':
        //是否可以点击
        if (curPage == num) {
          //当前页码 且不能点击
          return '<span class="page-btn page-btn-cur">' + num + '</span>';
        } else {
          //可以点击的页码
          //data-page记录第几页数据
          return '<a href="javascript:;" class="page-btn" data-page="' + num + '" data-field="btn" >' + num + '</a>';
        }
        break;
      case 'prev':
        if (curPage == 1) {
          return '<span class="dir-btn prev-btn disabled" ><i class="fa fa-angle-left" ></i></span>';
        } else {
          return '<a href="javascript:;" class="dir-btn prev-btn" data-field="prev"><i class="fa fa-angle-left" data-field="prev"></i></a>';
        }
        break;
      case 'next':
        if (curPage == pages) {
          return '<span class="dir-btn next-btn disabled"><i class="fa fa-angle-right"></i></span>';
        } else {
          return '<a href="javascript:;" class="dir-btn next-btn" data-field="next"><i class="fa fa-angle-right" data-field="next"></i></a>';
        }
        break;
      case 'points':
        return '<span class="points">...</span>';
        break;
    }
  }

  function makeBtnGroup(start, end) {
    for (var i = start; i <= end; i++) {
      btnGroup += pageBtnTpl('btn', i, curPage);
    }
  }

  function render() {
    btnGroup += pageBtnTpl('prev', pages, curPage);

    if (pages > 7) {
      //第一种情况 页码1 页码2 页码3 ... 页码n 页码n+1
      //小于3个时，循环3个按钮，其中两个可以点击，另外一个不能点击
      if (curPage < 3) {
        makeBtnGroup(1, 3, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(pages - 1, pages, curPage);
      } else if (curPage >= 3 && curPage < 5) {
        //第二种情况 
        makeBtnGroup(1, curPage + 1, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(pages - 1, pages, curPage);
      } else if (curPage >= 5 && curPage < pages - 3) {
        //第三种情况 
        makeBtnGroup(1, 2, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(curPage - 1, curPage + 1, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(pages - 1, pages, curPage);
      } else if (curPage >= pages - 4 && curPage <= pages - 1) {
        //第四种情况
        makeBtnGroup(1, 2, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(curPage - 1, pages, curPage);
      } else if (curPage == pages) {
        //第五种情况
        makeBtnGroup(1, 2, curPage);
        btnGroup += pageBtnTpl('points');
        makeBtnGroup(curPage - 2, pages, curPage);
      }
    } else {
      //第六种情况
      makeBtnGroup(1, pages, curPage);
    }
    btnGroup += pageBtnTpl('next', pages, curPage);
    oBtnBox.innerHTML = btnGroup;
  }

}

;
var initCommentModule = (function (doc, initPageBtns) {

  //获取节点
  //隐藏对话框
  var oCommentEditBoard = doc.getElementsByClassName('J_commentEditBoard')[0],
    //星星旁边的文字描述盒子
    oStarTip = doc.getElementsByClassName('J_starTip')[0],
    //拿到星星列表里的所有项目
    oStarsItems = doc.getElementsByClassName('J_hoverStar'),
    //文本区域下面的数字提示 0/1000
    oTextCount = doc.getElementsByClassName('J_txtCount')[0],
    // 提交评论按钮
    oSubmitBtn = doc.getElementsByClassName('J_submitBtn')[0],
    // 输入文本区域
    oEditText = doc.getElementsByClassName('J_editTxt')[0],
    //评论列表的tab栏的所有单选项
    oRadioTabItems = doc.getElementsByClassName('tab-radio'),
    //加载中 盒子
    oLoading = doc.getElementsByClassName('J_loading')[0],
    //评论列表 盒子
    oCommentList = doc.getElementsByClassName('J_commentList')[0],
    //好评度 
    oStatisticsNum = doc.getElementsByClassName('J_statisticsNum')[0],
    //分页 盒子
    oBtnBox = doc.getElementsByClassName('J_btnBox')[0],
    //提示信息 模板
    warningTip = doc.getElementById('J_warningTip').innerHTML,
    // tpl字符串替换 模板
    itemTpl = doc.getElementById('J_itemTpl').innerHTML,
    // 追加评论 模板
    addCommentTpl = doc.getElementById('J_addCommentTpl').innerHTML,
    //定时器
    t = null,
    //初始化星星数量
    starNum = 5,
    //初始化tab 全部0/好评1/中评2/差评3的data-id值
    fieldId = 0,
    //初始化页码
    // pages = 0,
    //当前页
    curPage = 1,

    //初始化毫秒数
    delayTime = 300;

  // 接口
  var APIs = {
    submitComment: 'http://localhost/api_for_study/index.php/Comment/submitComment',
    getComments: 'http://localhost/api_for_study/index.php/Comment/getComments'
  }

  return {
    //点击 立即评论 按钮显示评论对话框
    openBoard: function () {
      //显示评论对话框盒子
      oCommentEditBoard.style.display = 'block';
    },
    //抽象方法：隐藏对话框
    closeBoard: function () {
      //隐藏评论对话框盒子
      oCommentEditBoard.style.display = 'none';
      //重置对话框内容信息
      this._restoreBoardStatus();
    },
    //五星选择
    starsHover: function (e) {
      var e = e || window.event,
        tar = e.target || e.srcElement,
        tagName = tar.tagName.toLowerCase();

      if (tagName === 'i') {
        //查找被点击的星星下标
        var thisIdx = [].indexOf.call(oStarsItems, tar),
          len = oStarsItems.length,
          thisStarItem = oStarsItems[thisIdx],
          item;

        //更改文本盒子的显示内容
        oStarTip.innerHTML = thisStarItem.getAttribute('data-title');

        //保存当前星星数量
        starNum = thisStarItem.getAttribute('data-count');

        //遍历添加类名
        for (var i = 0; i < len; i++) {
          item = oStarsItems[i];

          if (i <= thisIdx) {
            //防止鼠标经过时不停新增active
            //当没有active类名时才能添加
            if (item.className.indexOf('active') === -1) {
              item.className += ' active';
            }
          } else {
            item.className = 'fa fa-star J_hoverStar'
          }
        }

      }
    },
    //填写评论
    editInput: function () {
      // 去掉空格
      var val = trimSpace(oEditText.value),
        valLen = val.length;

      // 将文本域文本值实时更新 0/1000
      oTextCount.innerHTML = valLen;

      // 高亮/变灰 提交评论 按钮
      if (valLen >= 15 && valLen <= 1000) {
        this.submitBtnChange({
          //真 旋转的图标/假 提交评论 字样
          txtChange: false,
          //真 按钮不可用 灰色/假 可用 高亮显示
          isDisabled: false
        });
      } else {
        //按钮变灰 按钮不可用
        this.submitBtnChange({
          txtChange: false,
          isDisabled: true
        });
      }
    },
    //提交评论
    submitComment: function (userId) {
      var val = oEditText.value,
        len = trimSpace(val).length,
        _self = this;

      if (len >= 15 && len <= 1000) {
        // 请求数据
        xhr.ajax({
          url: APIs.submitComment,
          type: 'POST',
          data: {
            userId: userId,
            starNum: starNum,
            comment: val
          },
          success: function (data) {
            var errorCode = data.error_code,
              oFirstCommentItem = oCommentList.getElementsByClassName('comment-item')[0];

            //管理 提交评论 按钮 文本内容
            _self.submitBtnChange({
              //真 旋转的图标/假 提交评论 字样
              txtChange: true,
              //真 按钮不可用 灰色/假 可用 高亮显示
              isDisabled: true
            });

            t = setTimeout(function () {
              _self.submitBtnChange({
                //真 旋转的图标/假 提交评论 字样
                txtChange: false,
                //真 按钮不可用 灰色/假 可用 高亮显示
                isDisabled: false
              });
              //清除计时器
              clearTimeout(t);
              if (errorCode === '10010') {
                alert('您以对该课程做了评价，感谢您');
                return;
              }

              //根据后端返回的id_add_comment字段0/1判断是否为首次评论/追加评论
              if (data.res.is_add_comment === '0') {
                //先判断有没有第一条评论，如有就insertBefore,没有就appendChild
                //顺序： 顶部插入最新评论
                if (oFirstCommentItem) {
                  //插入单条评论 模板字符串替换后生成的dom
                  //第二参数： 插入到哪一项之前
                  oCommentList.insertBefore(_self._makeItemDom(data.res), oFirstCommentItem);
                } else {
                  //清空清理列表
                  oCommentList.innerHTML = '';
                  //插入单条评论 模板字符串替换后生成的dom
                  oCommentList.appendChild(_self._makeItemDom(data.res));
                }
              } else if (data.res.is_add_comment === '1') {
                //不刷新页面可以直接追加评论
                _self._appendAddComment(data.res);
              }
              // 根据评价数量计算评论条数
              _self.setTabStarNum(data.num);
              //重置对话框
              _self._restoreBoardStatus();
              //关闭对话框
              _self.closeBoard();
            }, delayTime)
          },
          //请求失败
          error: function () {
            //警告
            alert('对不起，提交评论失败，请重试');
          }
        });
      }
    },
    //功能一：等待时是旋转图标 非等待时按钮文本为 点击提交
    //功能二：没有内容时不能点击 按钮灰色状态
    //管理 提交评论 按钮 样式显示
    submitBtnChange: function (opt) {
      //如果为两个参数，建议对象保存 多参数时，自定义命名便于管理维护
      var txtChange = opt.txtChange,
        isDisabled = opt.isDisabled;

      //如果txtChange为真为旋转的图标 false为 提交评论 字样
      if (txtChange) {
        oSubmitBtn.innerHTML = '<i class="fa fa-spinner fa-spin"></i>';
      } else {
        oSubmitBtn.innerHTML = '提交评论';
      }

      //如果isDisabled为真 按钮可用 高亮显示
      if (isDisabled) {
        //变灰色 
        oSubmitBtn.className += ' disabled';
        oSubmitBtn.setAttribute('disabled', 'disabled');
      } else {
        // 高亮 提交评论 按钮
        oSubmitBtn.className = 'comment-btn submit J_submitBtn';
        oSubmitBtn.removeAttribute('disabled');
      }
    },
    //功能一： 根据评价数量计算评论条数
    //功能二： 实时计算好评度
    setTabStarNum: function (arr) {
      var oRadioCount = null;
      arr.forEach(function (elem, index) {
        // 找到单选项下的数量的文本标签
        oRadioCount = oRadioTabItems[index].getElementsByClassName('radio-count')[0];
        oRadioCount.innerHTML = elem;
      });

      //数组例子：arr = [5, 3, 1, 1] => [全部/好评/中评/差评]
      oStatisticsNum.innerHTML = arr[0] === '0' ? '-' : Math.ceil(arr[1] / arr[0] * 100) + '%';

    },
    // 切换全部/好评/中评/差评
    radioTabClick: function (e) {
      var e = e || window.event,
        tar = e.target || e.srcElement,
        className = tar.className;

      if (className === 'radio-txt' || className === 'radio-icon') {
        var oParent = tar.parentNode,
          len = oRadioTabItems.length,
          item;

        //根据label标签data-id属性发送id到后端请求相应的数据列表
        fieldId = oParent.getAttribute('data-id');

        //所有的类名都为tab-radio
        for (var i = 0; i < len; i++) {
          item = oRadioTabItems[i];
          item.className = 'tab-radio';
        }
        //被点击父级项类名为tab-radio cur
        oParent.className += ' cur';
        //切换时把当前页改为1
        curPage = 1;

        this.getComments({
          fieldId: fieldId,
          pages: curPage - 1
        });
      }
    },
    //点击分页切换评论列表
    pageBtnClick: function () {
      var e = e || window.event,
        tar = e.target || e.srcElement,
        field = tar.getAttribute('data-field');

      //找到span/i 标签上的data-field属性进行判断
      if (field) {
        switch (field) {
          case 'btn':
            curPage = parseInt(tar.getAttribute('data-page'));
            break;
          case 'prev':
            //往前
            curPage -= 1;
            break;
          case 'next':
            //往后
            curPage += 1;
            break;
        }
        this.getComments({
          fieldId: fieldId,
          //后端页数从0开始
          pages: curPage - 1
        })
      }
    },
    // 获取评论数据列表
    getComments: function (opt) {
      var _self = this,
        fieldId = opt.fieldId,
        pages = opt.pages;

      //根据id请求对应的全部/好评/中评/差评 列表
      xhr.ajax({
        url: APIs.getComments,
        type: 'POST',
        data: {
          field: fieldId,
          page: pages
        },
        success: function (data) {
          console.log(data);
          //获取后端分页数据
          pages = data.pages;

          var num = data.num,
            data = data.res,
            len = data.length;

          //显示 加载中
          oLoading.style.display = 'block';
          t = setTimeout(function () {
            //更新tab 好评(0)/中评(0)/差评(0) 的数字
            _self.setTabStarNum(num);
            //隐藏 加载中
            oLoading.style.display = 'none';
            //先清空评论列表
            oCommentList.innerHTML = '';
            clearTimeout(t);

            //没有数据时显示 暂无评论 盒子
            if (len <= 0) {
              _self._setWarningTip('暂无评论');
              return;
            }

            //如果多页情况才渲染
            if (pages > 1) {
              initPageBtns(pages, curPage);
            } else {
              //清空 分页盒子
              oBtnBox.innerHTML = '';
            }

            //把渲染好的模板字符串插入评论列表节点
            oCommentList.appendChild(_self.renderList(data));
          }, delayTime);
        },
        //请求失败
        error: function () {
          //更改 提示信息 盒子的文本内容
          _self._setWarningTip('获取评论列表失败');
        }
      })
    },
    //重置对话框内容信息
    _restoreBoardStatus: function () {
      //重置5星
      var starLen = oStarsItems.length,
        item;

      for (var i = 0; i < starLen; i++) {
        item = oStarsItems[i];
        item.className += ' active';
      }
      //重置为默认5星好评
      oStarTip.innerHTML = oStarsItems[4].getAttribute('data-title');
      starNum = oStarsItems[4].getAttribute('data-count');

      //清空文本域
      oEditText.value = '';
      // 将文本域文本值改回 0/1000
      oTextCount.innerHTML = '0';
      //按钮 文本值 改回 提交评论 
      oSubmitBtn.innerHTML = '提交评论';
      this.submitBtnChange({
        //真 旋转的图标/假 提交评论 字样
        txtChange: false,
        //真 按钮不可用 灰色/假 可用 高亮显示
        isDisabled: true
      });
    },
    //修改 提示信息 盒子的内容
    _setWarningTip: function (text) {
      //把提示信息的字符串添加到评论列表盒子里
      oCommentList.innerHTML = warningTip.replace(/{{(.*?)}}/gim, text);
    },
    /**
     * _makeItemDom
     * 功能一：模板字符串处理
     * 功能二：创建单条评论 
     * 功能三：追加评论
     * @param {*} data 后端响应数据
     * @returns 替换好字符串的dom节点
     */
    _makeItemDom: function (data) {
      // tpl模板的包装容器
      var dom = doc.createElement('div'),
        starNum = data.star_num,
        count = 0;

      //新增类名
      dom.className = 'comment-item';
      //新增自定义属性 值为后端数据data.id
      dom.setAttribute('data-id', data.id);
      dom.innerHTML = itemTpl.replace(/{{(.*?)}}/gim, function (node, key) {
        // 当key打印isActive时自增
        key === 'isActive' && count++;
        return {
          avatar: 'img/' + data.avatar,
          nickname: data.nickname,
          comment: data.comment,
          uptime: getDateTime(data.uptime, 'dateTime'),
          //这里isActive 会根据规则显示评论每一项里星星的数量显示
          //<i class="fa fa-star {{isActive}}"></i>
          //评论条显示 5星的判断规则
          //count:每次遍历时key值为isActive拿到的count
          //starNum：后端拿到的数据num
          isActive: starNum >= count ? 'active' : ''
        } [key];
      });

      //判断data数据里是否存在add_comment字段
      //若存在，则为追加评论
      if (data.add_comment) {
        //继续追加模板字符
        dom.innerHTML += addCommentTpl.replace(/{{(.*?)}}/gim, function (node, key) {
          return {
            comment: data.add_comment.comment,
            uptime: getDateTime(data.add_comment.uptime, 'dateTime')
          } [key];
        });
      }

      return dom;
    },
    //不刷新页面可以直接追加评论
    _appendAddComment: function (data) {
      //选出所有评论项
      var oCommentItems = doc.getElementsByClassName('comment-item'),
        itemLen = oCommentItems.length,
        item;

      for (var i = 0; i < itemLen; i++) {
        item = oCommentItems[i];
        //数据库规则：如有追加评论id字段和add_id字段的数值相同
        if (item.getAttribute('data-id') === data.add_id) {
          //让评论条内容继续追加新的评论信息
          item.innerHTML += addCommentTpl.replace(/{{(.*?)}}/gim, function (node, key) {
            return {
              comment: data.comment,
              uptime: getDateTime(data.uptime, 'dateTime')
            } [key];
          });
        }
      }
    },
    //渲染页码
    renderList: function (data) {
      var frag = doc.createDocumentFragment(),
        _self = this;

      data.forEach(function (elem) {
        //插入替换好的模板字符串生成的dom
        frag.appendChild(_self._makeItemDom(elem));
      });
      return frag;
    }
  }
})(document, initPageBtns);